package org.example.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.example.common.PageResult;
import org.example.dto.*;
import org.example.entity.User;
import org.example.entity.UserStatus;
import org.example.exception.BusinessException;
import org.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用户业务逻辑层
 */
@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    /**
     * 创建用户
     */
    public User createUser(UserCreateDTO createDTO) {
        // 检查用户名是否已存在
        User existingUserByUsername = userRepository.findByUsername(createDTO.getUsername());
        if (existingUserByUsername != null) {
            throw new BusinessException("用户名已存在: " + createDTO.getUsername(), "USERNAME_EXISTS");
        }
        
        // 检查邮箱是否已存在
        User existingUserByEmail = userRepository.findByEmail(createDTO.getEmail());
        if (existingUserByEmail != null) {
            throw new BusinessException("邮箱已存在: " + createDTO.getEmail(), "EMAIL_EXISTS");
        }
        
        User user = new User(createDTO.getUsername(), createDTO.getEmail());
        userRepository.insert(user);
        return user;
    }
    
    /**
     * 创建用户（兼容旧接口）
     */
    public User createUser(String username, String email) {
        UserCreateDTO createDTO = new UserCreateDTO();
        createDTO.setUsername(username);
        createDTO.setEmail(email);
        return createUser(createDTO);
    }
    
    /**
     * 根据ID查找用户
     */
    public User findById(Long id) {
        return userRepository.selectById(id);
    }
    
    /**
     * 根据用户名查找用户
     */
    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
    
    /**
     * 获取所有用户
     */
    public List<User> findAllUsers() {
        return userRepository.selectList(null);
    }
    
    /**
     * 根据用户名模糊查询
     */
    public List<User> searchByUsername(String username) {
        return userRepository.findByUsernameContaining(username);
    }
    
    /**
     * 更新用户信息
     */
    public User updateUser(Long id, UserUpdateDTO updateDTO) {
        User user = userRepository.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在，ID: " + id, "USER_NOT_FOUND");
        }
        
        // 检查用户名冲突（排除当前用户）
        if (StringUtils.hasText(updateDTO.getUsername())) {
            User existingUserByUsername = userRepository.findByUsername(updateDTO.getUsername());
            if (existingUserByUsername != null && !existingUserByUsername.getId().equals(id)) {
                throw new BusinessException("用户名已被其他用户使用: " + updateDTO.getUsername(), "USERNAME_EXISTS");
            }
            user.setUsername(updateDTO.getUsername());
        }
        
        // 检查邮箱冲突（排除当前用户）
        if (StringUtils.hasText(updateDTO.getEmail())) {
            User existingUserByEmail = userRepository.findByEmail(updateDTO.getEmail());
            if (existingUserByEmail != null && !existingUserByEmail.getId().equals(id)) {
                throw new BusinessException("邮箱已被其他用户使用: " + updateDTO.getEmail(), "EMAIL_EXISTS");
            }
            user.setEmail(updateDTO.getEmail());
        }
        
        // 更新状态
        if (updateDTO.getStatus() != null) {
            user.setStatus(updateDTO.getStatus());
        }
        
        user.setUpdateTime(LocalDateTime.now());
        userRepository.updateById(user);
        return user;
    }
    
    /**
     * 更新用户信息（兼容旧接口）
     */
    public User updateUser(Long id, String username, String email) {
        UserUpdateDTO updateDTO = new UserUpdateDTO();
        updateDTO.setUsername(username);
        updateDTO.setEmail(email);
        return updateUser(id, updateDTO);
    }
    
    /**
     * 删除用户
     */
    public void deleteUser(Long id) {
        User user = userRepository.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在，ID: " + id, "USER_NOT_FOUND");
        }
        userRepository.deleteById(id);
    }
    
    /**
     * 分页查询用户
     */
    public PageResult<User> findUsersWithPage(UserPageDTO pageDTO) {
        Page<User> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        
        // 关键字搜索（用户名或邮箱）
        if (StringUtils.hasText(pageDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper
                    .like("username", pageDTO.getKeyword())
                    .or()
                    .like("email", pageDTO.getKeyword()));
        }
        
        // 状态筛选
        if (pageDTO.getStatus() != null) {
            queryWrapper.eq("status", pageDTO.getStatus());
        }
        
        // 排序
        if (StringUtils.hasText(pageDTO.getSortBy())) {
            if ("desc".equalsIgnoreCase(pageDTO.getSortOrder())) {
                queryWrapper.orderByDesc(pageDTO.getSortBy());
            } else {
                queryWrapper.orderByAsc(pageDTO.getSortBy());
            }
        } else {
            queryWrapper.orderByDesc("create_time");
        }
        
        IPage<User> result = userRepository.selectPage(page, queryWrapper);
        
        return new PageResult<>(
                result.getRecords(),
                result.getTotal(),
                (int) result.getSize(),
                (int) result.getCurrent(),
                (int) result.getPages()
        );
    }
    
    /**
     * 批量操作用户
     */
    @Transactional
    public void batchOperation(UserBatchDTO batchDTO) {
        if (batchDTO.getUserIds() == null || batchDTO.getUserIds().isEmpty()) {
            throw new BusinessException("用户ID列表不能为空", "EMPTY_USER_IDS");
        }
        
        switch (batchDTO.getOperationType()) {
            case "delete":
                batchDelete(batchDTO.getUserIds());
                break;
            case "updateStatus":
                if (batchDTO.getStatus() == null) {
                    throw new BusinessException("批量更新状态时，状态不能为空", "EMPTY_STATUS");
                }
                batchUpdateStatus(batchDTO.getUserIds(), batchDTO.getStatus());
                break;
            default:
                throw new BusinessException("不支持的操作类型: " + batchDTO.getOperationType(), "UNSUPPORTED_OPERATION");
        }
    }
    
    /**
     * 批量删除用户
     */
    private void batchDelete(List<Long> userIds) {
        userRepository.deleteBatchIds(userIds);
    }
    
    /**
     * 批量更新用户状态
     */
    private void batchUpdateStatus(List<Long> userIds, UserStatus status) {
        List<User> users = userRepository.selectBatchIds(userIds);
        if (users.isEmpty()) {
            throw new BusinessException("未找到要更新的用户", "USERS_NOT_FOUND");
        }
        
        users.forEach(user -> {
            user.setStatus(status);
            user.setUpdateTime(LocalDateTime.now());
        });
        
        users.forEach(user -> userRepository.updateById(user));
    }
    
    /**
     * 获取用户统计信息
     */
    public Map<String, Object> getUserStats() {
        long totalUsers = userRepository.selectCount(null);
        long activeUsers = userRepository.selectCount(new QueryWrapper<User>().eq("status", UserStatus.ACTIVE));
        long inactiveUsers = userRepository.selectCount(new QueryWrapper<User>().eq("status", UserStatus.INACTIVE));
        long bannedUsers = userRepository.selectCount(new QueryWrapper<User>().eq("status", UserStatus.BANNED));
        
        return Map.of(
                "totalUsers", totalUsers,
                "activeUsers", activeUsers,
                "inactiveUsers", inactiveUsers,
                "bannedUsers", bannedUsers
        );
    }
    
    /**
     * 获取用户总数
     */
    public long getUserCount() {
        return userRepository.countUsers();
    }
}